package server.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import server.demo.dto.CreateSeatRequest;
import server.demo.dto.SeatDTO;
import server.demo.entity.Carriage;
import server.demo.entity.Seat;
import server.demo.repository.CarriageRepository;
import server.demo.repository.SeatRepository;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Transactional
public class SeatService {
    
    @Autowired
    private SeatRepository seatRepository;
    
    @Autowired
    private CarriageRepository carriageRepository;
    
    public List<SeatDTO> getSeatsByCarriageId(Long carriageId) {
        return seatRepository.findByCarriageIdOrderBySeatNumber(carriageId)
                .stream()
                .map(SeatDTO::new)
                .collect(Collectors.toList());
    }
    
    public List<SeatDTO> getSeatsByTrainId(Long trainId) {
        return seatRepository.findSeatsByTrainId(trainId)
                .stream()
                .map(SeatDTO::new)
                .collect(Collectors.toList());
    }
    
    public List<SeatDTO> getAvailableSeatsByTrainId(Long trainId) {
        return seatRepository.findAvailableSeatsByTrainId(trainId)
                .stream()
                .map(SeatDTO::new)
                .collect(Collectors.toList());
    }
    
    public List<SeatDTO> getAvailableSeatsByCarriageId(Long carriageId) {
        return seatRepository.findAvailableSeatsByCarriageId(carriageId)
                .stream()
                .map(SeatDTO::new)
                .collect(Collectors.toList());
    }
    
    public Optional<SeatDTO> getSeatById(Long id) {
        return seatRepository.findById(id)
                .map(SeatDTO::new);
    }
    
    public SeatDTO createSeat(CreateSeatRequest request) {
        Optional<Carriage> carriage = carriageRepository.findById(request.getCarriageId());
        if (carriage.isEmpty()) {
            throw new RuntimeException("车厢不存在");
        }
        
        if (seatRepository.existsByCarriageIdAndSeatNumber(request.getCarriageId(), request.getSeatNumber())) {
            throw new RuntimeException("该车厢的座位号已存在");
        }
        
        Seat seat = new Seat();
        seat.setCarriage(carriage.get());
        seat.setSeatNumber(request.getSeatNumber());
        seat.setSeatType(Seat.SeatType.valueOf(request.getSeatType()));
        seat.setPrice(request.getPrice());
        seat.setIsAvailable(true);
        
        Seat savedSeat = seatRepository.save(seat);
        return new SeatDTO(savedSeat);
    }
    
    public SeatDTO updateSeat(Long id, CreateSeatRequest request) {
        Optional<Seat> seatOpt = seatRepository.findById(id);
        if (seatOpt.isEmpty()) {
            throw new RuntimeException("座位不存在");
        }
        
        Seat seat = seatOpt.get();
        
        // 如果座位号改变，检查是否冲突
        if (!seat.getSeatNumber().equals(request.getSeatNumber()) && 
            seatRepository.existsByCarriageIdAndSeatNumber(seat.getCarriage().getId(), request.getSeatNumber())) {
            throw new RuntimeException("该车厢的座位号已存在");
        }
        
        seat.setSeatNumber(request.getSeatNumber());
        seat.setSeatType(Seat.SeatType.valueOf(request.getSeatType()));
        seat.setPrice(request.getPrice());
        
        Seat savedSeat = seatRepository.save(seat);
        return new SeatDTO(savedSeat);
    }
    
    public void toggleSeatAvailability(Long id) {
        Optional<Seat> seatOpt = seatRepository.findById(id);
        if (seatOpt.isEmpty()) {
            throw new RuntimeException("座位不存在");
        }
        
        Seat seat = seatOpt.get();
        seat.setIsAvailable(!seat.getIsAvailable());
        seatRepository.save(seat);
    }
    
    public void deleteSeat(Long id) {
        if (!seatRepository.existsById(id)) {
            throw new RuntimeException("座位不存在");
        }
        seatRepository.deleteById(id);
    }
}